package com.ponhu.ea2.goodsCenter.provider.facade.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.ponhu.ea2.constants.CommonConstant;
import com.ponhu.ea2.constants.DictConstant;
import com.ponhu.ea2.entity.*;
import com.ponhu.ea2.enums.PropertyTypeEnum;
import com.ponhu.ea2.goodsCenter.provider.mapper.*;
import com.ponhu.ea2.goodsCenter.provider.service.*;
import com.ponhu.ea2.goodsCenter.provider.utils.ProBeanUtils;
import com.ponhu.ea2.scmcenter.model.enums.procurement.ProcurementTypeEnum;
import com.ponhu.ea2.scmcenter.model.enums.putware.PutWareHouseWayEnum;
import com.ponhu.ea2.service.facade.CommonApiService;
import com.ponhu.ea2.vo.*;
import com.ponhu.ea2.wmscenter.facade.bms.PhWarehouseFacade;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@DubboService(version = "1.0.0", interfaceClass = CommonApiService.class, timeout = 6000)
public class CommonApiServiceImpl implements CommonApiService {

    @Autowired
    private PhSeriesMapper phSeriesMapper;
    @Autowired
    private PhCategoryMapper phCategoryMapper;
    @Autowired
    private PhPropertyMapper phPropertyMapper;

    @Autowired
    private PhSeriesService phSeriesService;
    @Autowired
    private MaterialService materialService;
    @Autowired
    private PhBrandService phBrandService;
    @Autowired
    private PhModelService phModelService;
    @Autowired
    private PhPropertyService phPropertyService;
    @Autowired
    private PhCategoryService phCategoryService;
    @Autowired
    private PhCountriesService phCountriesService;
    @Autowired
    private PhSysDictItemService phSysDictItemService;
    @Autowired
    private PhPropertyValueService phPropertyValueService;

    @DubboReference(version = "1.0.0", check = false, timeout = 60000)
    private PhWarehouseFacade phWarehouseFacade;
    @Autowired
    private PhInventoryDetailMapper phInventoryDetailMapper;


    /**
     * 获取全部货品附件字段项
     *
     * @return
     */
    @Override
    public List<PhSysDictItemVo> getAllInventoryAnnexs() {

        List<PhSysDictItem> phSysDictItems = phSysDictItemService
                .getDictItemsByType(DictConstant.INVENTORY_ANNEX);

        return phSysDictItems.stream()
                .map(item -> ProBeanUtils.copyProperties(item, PhSysDictItemVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 获取全部货品配件字段项
     *
     * @return
     */
    @Override
    public List<PhSysDictItemVo> getAllInventoryAccessorys() {

        List<PhSysDictItem> phSysDictItems = phSysDictItemService
                .getDictItemsByType(DictConstant.INVENTORY_ACCESSORY);

        return phSysDictItems.stream()
                .map(item -> ProBeanUtils.copyProperties(item, PhSysDictItemVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 获取指定类目ID所属的全部货品属性
     *
     * @param level
     * @param categoryId
     * @return
     */
    @Override
    public List<PhPropertyEditVo> getAllInventoryProps(Integer level, Long categoryId) {
        return getAllPropsByType(level, categoryId, PropertyTypeEnum.INVENTORY.getCode());

    }

    /**
     * 获取指定类目ID所属的全部属性
     *
     * @param level
     * @param categoryId
     * @param type
     * @return
     */
    @Override
    public List<PhPropertyEditVo> getAllProps(Integer level, Long categoryId, Integer type) {
        return getAllPropsByType(level, categoryId, type);
    }

    /**
     * 获取指定类目ID所属的全部物料属性
     *
     * @param level
     * @param categoryId
     * @return
     */
    @Override
    public List<PhPropertyEditVo> getAllMaterialProps(Integer level, Long categoryId) {
        return getAllPropsByType(level, categoryId, PropertyTypeEnum.MATERIAL.getCode());
    }

    private List<PhPropertyEditVo> getAllPropsByType(Integer level, Long categoryId, Integer propertyType) {
        List<PhCategoryLevel3Vo> categoryLevel3Vos = Lists.newArrayList();
        if (CommonConstant.CATEGORY_LEVEL_1.equals(level)) {
            categoryLevel3Vos = phCategoryMapper
                    .getCategoryLevel3VosById(categoryId, null, null);
        }
        if (CommonConstant.CATEGORY_LEVEL_2.equals(level)) {
            categoryLevel3Vos = phCategoryMapper
                    .getCategoryLevel3VosById(null, categoryId, null);
        }
        if (CommonConstant.CATEGORY_LEVEL_3.equals(level)) {
            categoryLevel3Vos = phCategoryMapper
                    .getCategoryLevel3VosById(null, null, categoryId);
        }

        if (CollectionUtils.isEmpty(categoryLevel3Vos)) {
            return Lists.newArrayList();
        }

        Set<Long> categoryIds = categoryLevel3Vos.stream().flatMap(level3Vo -> Stream.of(level3Vo.getLevel1Id(),
                level3Vo.getLevel2Id(), level3Vo.getLevel3Id())).collect(Collectors.toSet());

        return phPropertyMapper.getPropValuesByCategoryIds(propertyType, categoryIds);
    }

    /**
     * 获取全部货品类型字段项
     *
     * @return
     */
    @Override
    public List<PhSysDictItemVo> getAllInventoryTypes() {

        List<PhSysDictItem> phSysDictItems = phSysDictItemService
                .getDictItemsByType(DictConstant.INVENTORY_TYPE);

        return phSysDictItems.stream()
                .map(item -> ProBeanUtils.copyProperties(item, PhSysDictItemVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 获取全部货品来源字段项
     *
     * @return
     */
    @Override
    public List<PhSysDictItemVo> getAllInventoryChannels() {

        List<PhSysDictItem> phSysDictItems = phSysDictItemService
                .getDictItemsByType(DictConstant.INVENTORY_CHANNEL);

        return phSysDictItems.stream()
                .map(item -> ProBeanUtils.copyProperties(item, PhSysDictItemVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 获取全部入库方式
     *
     * @return
     */
    @Override
    public List<PhSysDictItemVo> getAllWarehouseWays() {
        return Arrays.stream(PutWareHouseWayEnum.values()).map(i ->
                        new PhSysDictItemVo().setValue(i.getType().toString()).setValue(i.getName()))
                .collect(Collectors.toList());
    }

    /**
     * 获取全部成色类型字段项
     *
     * @return
     */
    @Override
    public List<PhSysDictItemVo> getAllConditionTypes() {

        List<PhSysDictItem> phSysDictItems = phSysDictItemService
                .getDictItemsByType(DictConstant.CONDITION_TYPE);

        return phSysDictItems.stream()
                .map(item -> ProBeanUtils.copyProperties(item, PhSysDictItemVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 获取全部品牌或搜索品牌
     *
     * @param name
     * @return
     */
    @Override
    public List<PhBrandVo> getPhBrandsByName(String name) {

        return phBrandService.getPhBrandsByName(name, true).stream()
                .map(brand -> ProBeanUtils.copyProperties(brand, PhBrandVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 获取全部品牌或搜索品牌
     *
     * @param name
     * @return
     */
    @Override
    public List<PhBrandVo> getPhBrandsByName(String name, Boolean isAll) {

        return phBrandService.getPhBrandsByName(name, isAll).stream()
                .map(brand -> ProBeanUtils.copyProperties(brand, PhBrandVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 根据品牌或系列查询所有型号
     *
     * @return
     */
    @Override
    public List<PhModelVo> getPhModelsBySeries(Long seriesId) {

        return phModelService.getPhModelsBySeries(seriesId).stream()
                .map(brand -> ProBeanUtils.copyProperties(brand, PhModelVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 根据品牌或系列查询所有物料型号
     *
     * @param brandId
     * @param seriesId
     * @return
     */
    @Override
    public List<PhMaterialModelVo> getPhMaterialModelsByBrandOrSeries(Long brandId, Long seriesId) {

        // 根据品牌或系列查询所有物料信息集合
        List<Material> materialList = materialService.getPhModelsByBrandOrSeries(brandId, seriesId);
        if (CollectionUtils.isEmpty(materialList)) {
            return Lists.newArrayList();
        }

        // 根据型号ID集合查询获取对应型号信息集合并转Map(key:型号ID, value:型号名称)
        List<Long> modelIds = materialList.parallelStream()
                .map(Material::getModelId).distinct().collect(Collectors.toList());

        Map<Long, String> modelMap = phModelService.listByIds(modelIds).parallelStream()
                .collect(Collectors.toMap(PhModel::getId, PhModel::getModel));

        // 组合业务数据模型
        return materialList.parallelStream().map(material ->
                ProBeanUtils.copyProperties(material, PhMaterialModelVo.class)
                        .setMaterialId(material.getId())
                        .setModel(modelMap.get(material.getModelId()))).collect(Collectors.toList());
    }

    /**
     * 获取指定分级和父级类目ID的全部类目集合
     *
     * @param level
     * @param parentId
     * @return
     */
    @Override
    public List<PhCategoryVo> getPhCategorysByLevel(Integer level, Long parentId) {

        return phCategoryService.getPhCategorysByLevel(level, parentId, true).stream()
                .map(brand -> ProBeanUtils.copyProperties(brand, PhCategoryVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 获取指定分级和父级类目ID的全部类目集合
     *
     * @param level
     * @param parentId
     * @return
     */
    @Override
    public List<PhCategoryVo> getPhCategorysByLevel(Integer level, Long parentId, Boolean isAll) {

        return phCategoryService.getPhCategorysByLevel(level, parentId, isAll).stream()
                .map(brand -> ProBeanUtils.copyProperties(brand, PhCategoryVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 获取全部货源字段项
     *
     * @return
     */
    @Override
    public List<PhSysDictItemVo> getAllInventorySources() {
        List<PhSysDictItem> phSysDictItems = phSysDictItemService
                .getDictItemsByType(DictConstant.INVENTORY_SOURCE);

        return phSysDictItems.stream()
                .map(item -> ProBeanUtils.copyProperties(item, PhSysDictItemVo.class))
                .collect(Collectors.toList());
    }

    /**
     * 根据品牌获取所有的系列
     *
     * @param brandId
     * @return
     */
    @Override
    public List<PhSeriesVO> queryPhSeriesByBrandId(Long brandId) {

        List<PhSeries> phSeries = phSeriesMapper.selectList(new LambdaQueryWrapper<PhSeries>().eq(PhSeries::getBrandId, brandId));
        return phSeries.stream().map(item -> ProBeanUtils.copyProperties(item, PhSeriesVO.class)).collect(Collectors.toList());
    }

    /**
     * 根据多品牌品牌查询系列
     */
    @Override
    public List<PhSeriesVO> queryPhSeriesByBrandIds(List<Long> brandIds) {

        return phSeriesService.getListByBrandIds(brandIds).stream()
                .map(item -> ProBeanUtils.copyProperties(item, PhSeriesVO.class))
                .collect(Collectors.toList());
    }

    /**
     * 根据品牌获取所有的型号
     *
     * @param brandId
     * @return
     */
    @Override
    public List<PhModelVo> queryPhModelByBrandId(Long brandId) {

        List<PhModel> list = phModelService.getPhmodelsByBrandId(brandId);

        return list.stream().map(item -> ProBeanUtils.copyProperties(item, PhModelVo.class)).collect(Collectors.toList());
    }

    @Resource
    PhModelMapper phModelMapper;

    /**
     * 根据多品牌查询所有型号
     */
    @Override
    public List<PhModelVo> queryPhModelByBrandIds(List<Long> brandIds) {
        if (CollectionUtils.isEmpty(brandIds)) return Lists.newArrayList();
        /*return phModelService.getListByBrandId(brandIds).stream()
                .map(item -> ProBeanUtils.copyProperties(item, PhModelVo.class))
                .collect(Collectors.toList());*/
        return phModelMapper.queryPhModelVoBybrandIds(brandIds);
    }

    /**
     * 获取全部国家信息
     *
     * @return
     */
    @Override
    public List<String> getAllCountries() {

        return phCountriesService.list().stream()
                .map(PhCountries::getCountry).collect(Collectors.toList());
    }

    @Override
    public List<PhCountriesVo> getAllCountriesForVo() {
        return phCountriesService.getAllCountriesForVo();
    }


    /**
     * 获取指定类目ID的三级类目信息
     *
     * @param level3CategoryId
     * @return
     */
    @Override
    public PhCategoryLevel3Vo getCategoryLevel3VoById(Long level3CategoryId) {

        return phCategoryMapper.getCategoryLevel3VosByThirdCategoryId(level3CategoryId);
    }

    /**
     * 获取指定类目名称的三级类目信息
     *
     * @param level3CategoryName
     * @return
     */
    @Override
    public PhCategoryLevel3Vo getCategoryLevel3VoByName(String level3CategoryName) {

        return phCategoryMapper.getCategoryLevel3VosByThirdCategoryName(level3CategoryName);
    }

    /**
     * 根据品类Id获取品类信息
     *
     * @param categoryId
     * @return
     */
    @Override
    public PhCategoryVo getCategoryByCategoryId(Long categoryId) {
        if (categoryId == null) {
            return null;
        }
        PhCategory category = phCategoryService.getById(categoryId);
        if (category == null) {
            return null;
        }
        PhCategoryVo phCategoryVo = new PhCategoryVo();
        BeanUtils.copyProperties(category, phCategoryVo);

        return phCategoryVo;
    }

    /**
     * 获取全部采购类型
     *
     * @return
     */
    @Override
    public List<PhSysDictItemVo> getAllPurchaseTypes() {
        return Arrays.stream(ProcurementTypeEnum.values()).map(i ->
                        new PhSysDictItemVo().setValue(i.getType().toString()).setValue(i.getName()))
                .collect(Collectors.toList());
    }

    /**
     * 获取全部采购渠道
     *
     * @return
     */
    @Override
    public List<PhSysDictItemVo> getAllPurchaseChannel() {
        return null;
    }

    /**
     * 获取指定类目ID所属的全部指定类型的属性
     *
     * @return
     */
    @Override
    public List<PhPropertyVo> getAllTypeProps(Long categoryId, String name) {

        return phPropertyService.getPropertyByCategoryId(categoryId, CommonConstant.CATEGORY_LEVEL_3)
                .stream().filter(prop -> prop.getName().contains(name)).map(prop ->
                        new PhPropertyVo().setPropertyId(prop.getId()).setPropertyName(prop.getName()))
                .collect(Collectors.toList());
    }

    /**
     * 获取指定属性ID所属的全部属性值
     *
     * @return
     */
    @Override
    public List<PhPropertyVo> getAllPropValues(Long propId) {

        return phPropertyValueService.getValuesByPropIds(Arrays.asList(propId))
                .stream().map(value -> new PhPropertyVo()
                        .setPropertyId(value.getId()).setPropertyName(value.getValue()).setPropertyValue(value.getValue()))
                .collect(Collectors.toList());
    }

}
